package hit.core;

import static org.junit.Assert.*;

import java.util.Calendar;
import java.util.Date;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class ProductTest {
	
	Product product;
	
	@Before
	public void SetUp() {
	
		product = new Product();
		
		product.SetCreation(new Date());
		product.SetBarcode(new Barcode("036725604919"));
		product.SetDescription("Testing");
		product.SetShelfLife(3);
		product.SetSize(new Size(2, Size.Unit.COUNT));
		product.SetThreeMonth(10);
	}
	
	@After
	public void TearDown() {
		
		product = null;
	}
	
	@Test
	public void TestIsValid() {
		
		Product badProduct = new Product();
		
		// Test new Product
		assertFalse("Invalid product should have returned false.", Product.IsValid(badProduct));
		
		// Set everything as valid values.
		
		assertTrue("Valid product should have returned true.", Product.IsValid(product));
	}

	@Test
	public void TestCreateItem() {
		StorageUnit testContainer = new StorageUnit("TestContainer");
		Date entryDate = new Date();
		Item newItem = product.CreateItem(testContainer, entryDate);
		
		// Test Item is valid.
		assertTrue("Failed to create valid product.", Item.IsValid(newItem));
		
		// Test for container.
		assertTrue("Item is in the wrong container.", newItem.GetContainer() == testContainer);
		
		// Test Product link is correct.
		assertTrue("Product type incorrect.", newItem.GetProduct() == product);
	}
	
	@Test
	public void TestSetAndGetCreation() {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		product.SetCreation(calendar.getTime());
		assertEquals("Creation date did not return expected value.", calendar.getTime(), product.GetCreation());
	}
	
	@Test
	public void TestSetAndGetBarcode() {
		Barcode testCode = new Barcode("036725604919");
		product.SetBarcode(testCode);
		assertEquals("Did not return expected Barcode \"036725604919\"", testCode, product.GetBarcode());
	}
	
	@Test
	public void TestSetLocalBarcode() {
		Barcode localCode = new Barcode("400000123455");
		product.SetBarcode(localCode);
		assertTrue(Product.IsValid(product));
	}
	
	@Test(expected=IllegalArgumentException.class)
	public void TestInvalidBarcode() {
		product.SetBarcode(new Barcode());
	}
	
	@Test
	public void TestSetAndGetDescription() {
		product.SetDescription("Hello world");
		assertEquals("Did not return expected value \"Hello World\"", "Hello world", product.GetDescription());
	}
	
	@Test
	public void TestSetAndGetSize() {
		Size size = new Size(12.1, Size.Unit.GALLONS);
		product.SetSize(size);
		assertEquals("Size was not correctly set.", size, product.GetSize());
	}
	
	@Test(expected=IllegalArgumentException.class)
	public void TestSetAndGetShelfLife() {
		product.SetShelfLife(12);
		assertEquals("Did not return expected value: 12", 12, product.GetShelfLife());
		
		product.SetShelfLife(0);
		assertEquals("Did not return expected value: 0", 0, product.GetShelfLife());
		
		// Test invalid ShelfLife
		product.SetShelfLife(-1);
	}
	
	@Test(expected=IllegalArgumentException.class)
	public void TestSetAndGetThreeMonths() {
		product.SetThreeMonth(35);
		assertEquals("Did not return expected value: 35", 35, product.GetThreeMonth());
		
		product.SetThreeMonth(0);
		assertEquals("Did not return expected value: 0", 0, product.GetThreeMonth());
		
		// Test invalid ShelfLife
		product.SetThreeMonth(-1);
	}
}
